/*
 * =====================================================================================
 *
 *       Filename:  str_regex.c
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  07/04/15 08:03:31
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Andy (gk), andy_y_li@163.com
 *        Company:  RD
 *
 * =====================================================================================
 */

#include "strRegex.h"
#include <stdlib.h>

using namespace std;

StrPattern::StrPattern(const char *str, const char *pattern, int pmatchLength)
{
    char errbuf[1024];
    int err = 0;

    _result = FATAL_ERROR;
    _matchCount = 0;
    _str = str;
    msgBuf = NULL;

    pmatch = (regmatch_t *)malloc(pmatchLength * sizeof(regmatch_t));
    if (pmatch == NULL) {
        cout << "Error on malloc: " << strerror(errno) << endl;
        return;
    }
    memset(pmatch, 0, pmatchLength);

    if(regcomp(&reg,pattern,REG_EXTENDED) < 0){
        regerror(err,&reg,errbuf,sizeof(errbuf));
        printf("err:%s\n",errbuf);
        _result = FATAL_ERROR;
        return;
    }
    
    err = regexec(&reg,str, pmatchLength, pmatch,0);
    
    if(err == REG_NOMATCH){
        printf("no match\n");
        _result = NO_MATCH;
        return;
    }else if(err){
        regerror(err,&reg,errbuf,sizeof(errbuf));
        printf("err:%s\n",errbuf);
        _result = FATAL_ERROR;
        return;
    }
    _result = OK;

    for(int i=0;i<pmatchLength && pmatch[i].rm_so!=-1;i++){
        int len = pmatch[i].rm_eo-pmatch[i].rm_so;
        if(len){
            _matchCount++;
        }
    }
}

StrPattern::~StrPattern()
{
    cout << "Destroy the memory..." << endl;
    if (pmatch) {
        free(pmatch);
        pmatch = NULL;
    }
    if (msgBuf) {
        free(msgBuf);
        msgBuf = NULL;
    }
    regfree(&reg);
}

PatternErrorCode StrPattern::result()
{
    return _result;
}

int StrPattern::matchCount()
{
    return _matchCount;
}

const char *StrPattern::getMatchString(int index)
{
    if (_result != OK || index >= _matchCount) {
        return NULL;
    }
    int len = pmatch[index].rm_eo - pmatch[index].rm_so;
    if (len == 0) {
        return NULL;
    }
    if (msgBuf) {
        free(msgBuf);
    }
    msgBuf = (char *)malloc((len + 1) * sizeof(char));
    if (msgBuf == NULL) {
        cout << "Error on malloc: " << strerror(errno) << endl;
        return NULL;
    }
    memset(msgBuf, '\0', (len + 1) * sizeof(char));
    memcpy(msgBuf, _str + pmatch[index].rm_so, len);

    return msgBuf;
}

